package top.mcwebsite.markdown.theme

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLinkStyles
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import compose_markdown.markdown.generated.resources.Res
import compose_markdown.markdown.generated.resources.checkbox
import compose_markdown.markdown.generated.resources.checkbox_active
import dev.snipme.highlights.model.SyntaxTheme
import dev.snipme.highlights.model.SyntaxThemes
import org.jetbrains.compose.resources.painterResource
import top.mcwebsite.markdown.utils.intToRoman
import top.mcwebsite.markdown.utils.numberToLetters

val LocalMarkdownTheme = compositionLocalOf { defaultMarkdownTheme }


data class MarkdownTheme(
    val text: TextStyle,
    val heading1Style: TextStyle = text.copy(fontSize = 32.sp, fontWeight = FontWeight.Bold),
    val heading2Style: TextStyle = text.copy(fontSize = 28.sp, fontWeight = FontWeight.Bold),
    val heading3Style: TextStyle = text.copy(fontSize = 24.sp, fontWeight = FontWeight.Bold),
    val heading4Style: TextStyle = text.copy(fontSize = 20.sp, fontWeight = FontWeight.Bold),
    val heading5Style: TextStyle = text.copy(fontSize = 18.sp, fontWeight = FontWeight.Bold),
    val heading6Style: TextStyle = text.copy(fontSize = 16.sp, fontWeight = FontWeight.Bold),
    val boldStyle: SpanStyle = text.toSpanStyle().copy(fontWeight = FontWeight.Bold),
    val italicStyle: SpanStyle = text.toSpanStyle().copy(fontStyle = FontStyle.Italic),
    val codeSpanStyle: SpanStyle = text.toSpanStyle().copy(background = Color.LightGray),
    val linkStyles: TextLinkStyles = run {
        val style = text.toSpanStyle().copy(color = Color.Blue)
        TextLinkStyles(
            style = style,
            hoveredStyle = style.copy(textDecoration = TextDecoration.Underline),
            pressedStyle = style.copy(textDecoration = TextDecoration.Underline)
        )
    },
    val strikethroughStyle: SpanStyle = text.toSpanStyle().copy(textDecoration = TextDecoration.LineThrough),
    val contentPadding: PaddingValues,
    val blockPadding: PaddingValues,
    val blockQuoteTheme: BlockQuoteTheme,
    val dividerTheme: DividerTheme,
    val orderListTheme: OrderListTheme,
    val unOrderedListTheme: UnOrderedListTheme,
    val codeFenceTheme: CodeFenceTheme,
    val tableTheme: TableTheme,
)

data class BlockQuoteTheme(
    val backgroundColor: Color,
    val quoteColor: Color,
    val quoteWidth: Dp,
    val quoteSpace: Dp,
    val quotePadding: PaddingValues,
)

data class DividerTheme(
    val padding: PaddingValues,
    val color: Color,
    val thickness: Dp,
)

data class OrderListTheme(
    val itemPadding: PaddingValues,
    val nextLevelSpace: Dp,
    val levelIndexToString: (level: Int, index: Int) -> String,
    val indexStyle: TextStyle,
    val indexContentSpace: Dp
)

data class UnOrderedListTheme(
    val itemPadding: PaddingValues,
    val nextLevelSpace: Dp,
    val itemIndicator: ItemIndicator,
    val checkBox: CheckBox,
) {
    data class ItemIndicator(
        val padding: PaddingValues,
        val size: Dp,
        val color: Color,
        val shape: Shape
    )

    data class CheckBox(
        val CheckBoxIcon: @Composable (Boolean) -> Unit
    )
}

data class CodeFenceTheme(
    val codeTextStyle: TextStyle,
    val backgroundColor: Color,
    val borderWidth: Dp,
    val borderColor: Brush,
    val borderShape: Shape,
    val codePadding: PaddingValues,
    val theme: SyntaxTheme
)

data class TableTheme(
    val headerTextStyle: TextStyle,
    val headerBackgroundColor: Color,
    val cellPadding: PaddingValues,
    val cellBorderColor: Color,
    val cellBorderWidth: Dp,
)

fun defaultLevelIndexToString(level: Int, index: Int): String {
    return when (level) {
        1 -> index.toString()
        2 -> numberToLetters(index)
        else -> intToRoman(index)
    }
}

val defaultMarkdownTheme = MarkdownTheme(
    text = TextStyle(
        fontSize = 16.sp
    ),
    contentPadding = PaddingValues(16.dp),
    blockPadding = PaddingValues(vertical = 5.dp),
    blockQuoteTheme = BlockQuoteTheme(
        backgroundColor = Color(0xFFE6E6E6),
        quoteColor = Color(0xFFB3B3B3),
        quoteWidth = 4.dp,
        quoteSpace = 10.dp,
        quotePadding = PaddingValues(vertical = 5.dp, horizontal = 10.dp)
    ),
    dividerTheme = DividerTheme(
        padding = PaddingValues(vertical = 10.dp),
        color = Color(0xFFDCDCDC),
        thickness = 2.dp
    ),
    orderListTheme = OrderListTheme(
        itemPadding = PaddingValues(vertical = 3.dp),
        nextLevelSpace = 30.dp,
        levelIndexToString = ::defaultLevelIndexToString,
        indexStyle = TextStyle(fontSize = 16.sp),
        indexContentSpace = 5.dp,
    ),
    unOrderedListTheme = UnOrderedListTheme(
        itemPadding = PaddingValues(vertical = 3.dp),
        nextLevelSpace = 30.dp,
        itemIndicator = UnOrderedListTheme.ItemIndicator(
            padding = PaddingValues(horizontal = 8.dp),
            size = 6.dp,
            color = Color.Black,
            shape = CircleShape
        ),
        checkBox = UnOrderedListTheme.CheckBox(
            CheckBoxIcon = @Composable { checked ->
                val modifier = Modifier
                    .padding(horizontal = 5.dp)
                    .size(24.dp)
                if (checked) {
                    Icon(painterResource(Res.drawable.checkbox_active), contentDescription = null, modifier = modifier)
                } else {
                    Icon(painterResource(Res.drawable.checkbox), contentDescription = null, modifier = modifier)
                }
            }
        ),
    ),
    codeFenceTheme = CodeFenceTheme(
        codeTextStyle = TextStyle(fontSize = 16.sp),
        backgroundColor = Color(0xFFF1F1F1),
        borderWidth = 1.dp,
        borderColor = SolidColor(Color.Gray),
        borderShape = RoundedCornerShape(5.dp),
        codePadding = PaddingValues(10.dp),
        theme = SyntaxThemes.atom(),
    ),
    tableTheme = TableTheme(
        headerTextStyle = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold),
        headerBackgroundColor = Color(0xFFE6E6E6),
        cellPadding = PaddingValues(5.dp),
        cellBorderColor = Color.Gray,
        cellBorderWidth = 1.dp,
    )
)
